﻿using Domain.Base;
using Domain.Entity;
using DtoFw;
using DtoFw.Query;
using DtoFw.Result;
using Repository;
using System.Collections.Generic;
using System.Linq;

namespace Service
{
    public class MainRoleService
    {
        private readonly MainRoleRepository rep_mainRole;
        private readonly MainRoleMapMenuRepository rep_mainRoleMapMenu;
        private readonly MainUserMapRoleRepository rep_mainUserMapRole;
        private readonly MainMenuRepository rep_mainMenu;

        public MainRoleService(MainRoleRepository mainRole, MainRoleMapMenuRepository mainRoleMapMenu,
            MainUserMapRoleRepository mainUserMapRole, MainMenuRepository mainMenu)
        {
            rep_mainRole = mainRole;
            rep_mainRoleMapMenu = mainRoleMapMenu;
            rep_mainUserMapRole = mainUserMapRole;
            rep_mainMenu = mainMenu;
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public BaseGenericResult<Pager<RoleResult>> Query(BaseQuery query)
        {
            BaseGenericResult<Pager<RoleResult>> baseResult = new BaseGenericResult<Pager<RoleResult>>();
            baseResult.Data = new Pager<RoleResult>();
            Pager<MainRoleEntity> pager = rep_mainRole.GetPagerList(query);
            baseResult.Data.TotalCount = pager.TotalCount;
            baseResult.Data.Data = Util.AutoMapperExtension.MapTo<MainRoleEntity, RoleResult>(pager.Data);
            return baseResult;
        }
        /// <summary>
        /// 获取指定角色对象
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public BaseGenericResult<RoleResult> QueryRole(long roleId)
        {
            MainRoleEntity roleInfo = rep_mainRole.Get(new BaseQuery() { Id = roleId });
            BaseGenericResult<RoleResult> responseDto = new BaseGenericResult<RoleResult>();
            responseDto.Data = new RoleResult();
            if (roleInfo != null)
            {
                responseDto.Data.Id = roleInfo.Id;
                responseDto.Data.Name = roleInfo.Name;
                responseDto.Data.Remark = roleInfo.Remark;
                responseDto.Data.CreateTime = roleInfo.CreateTime;
                responseDto.Data.roleMapMenuResult = GetRoleMapMenus(new RoleQuery() { RoleId = roleInfo.Id })?.Data;
            }
            return responseDto;
        }
        /// <summary>
        /// 移除菜单
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public BaseResult Delete(DeleteDto query)
        {
            bool result = false;
            BaseResult response = new BaseResult();
            result = rep_mainRole.DeleteBatch(new BaseOperate()
            {
                Ids = query.Ids,
                Modifyer = query.UserName,
                ModifyerId = query.UserId
            }) > 0;
            if (!result)
                return BaseResult.Failure("移除角色失败");
            result = rep_mainRoleMapMenu.Delete(new BaseOperate(), m => m.Where(t => query.Ids.Contains(t.Id))) > 0;
            return response;
        }
        /// <summary>
        /// 保存角色
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public BaseResult AddRole(RoleEditInfo request)
        {
            bool result = true;
            long roleId = 0;
            BaseResult response = new BaseResult();
            if (request.Id < 1)
            {
                MainRoleEntity roleInfo = rep_mainRole.Get(new BaseQuery(), m => m.Where(t => t.Name == request.Name));
                if (roleInfo != null)
                    return BaseResult.Failure("当前角色名已存在");
                roleInfo = new MainRoleEntity();
                roleInfo.Name = request.Name;
                roleInfo.Remark = request.Remark;
                roleId = rep_mainRole.Save(roleInfo).Id;
            }
            else
            {
                MainRoleEntity roleInfo = rep_mainRole.Get(new BaseQuery() { Id = request.Id });
                roleInfo.Name = request.Name;
                roleInfo.Remark = request.Remark;
                if (rep_mainRole.Save(roleInfo).Id > 0)
                {
                    List<long> roleIds = rep_mainRoleMapMenu.Query(new BaseQuery(), m => m.Where(t => t.RoleId == roleInfo.Id))?
                        .Select(x => x.Id)?.ToList();
                    if (roleIds != null && roleIds.Count > 0)
                        result = rep_mainRoleMapMenu.DeleteBatch(new BaseOperate() { Ids = roleIds }) > 0;
                    roleId = request.Id;
                }
            }
            if (result)
            {
                List<MainRoleMapMenuEntity> roleMapMenus = new List<MainRoleMapMenuEntity>();
                request.MenuIds.ForEach(t =>
                {
                    roleMapMenus.Add(new MainRoleMapMenuEntity()
                    {
                        RoleId = roleId,
                        MenuId = t
                    });
                });
                if (rep_mainRoleMapMenu.InsertBatch(roleMapMenus) > 0)
                    return response;
            }
            response.Success = false;
            response.Msg = "角色添加失败，内部错误";
            return response;
        }
        /// <summary>
        /// 获取角色分配菜单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<RoleMapMenuResult> GetRoleMapMenus(RoleQuery query)
        {
            if (query.RoleId < 1 && query.UserId < 1)
                return BaseGenericResult<RoleMapMenuResult>.Failure(new RoleMapMenuResult(), "参数异常");
            long? roleId = 0;
            if (query.RoleId == 0)
            {
                MainUserMapRoleEntity userMapRole = rep_mainUserMapRole.Get(new BaseQuery(),
                    t => t.Where(m => m.UserId == query.UserId));
                roleId = userMapRole?.RoleId;
            }
            else
            {
                roleId = query.RoleId;
            }
            //所有后台菜单
            List<MainMenuEntity> menuInfos = rep_mainMenu.Query(new BaseQuery(), t => t.Where(m => m.Type == 0))?.ToList();
            //角色菜单
            List<long> removeIds = new List<long>();
            List<MainRoleMapMenuEntity> baseRoleMapMenus = rep_mainRoleMapMenu.Query(new BaseQuery(), m => m.Where(t => t.RoleId == roleId))?.ToList();
            List<long> checkMenuIds = baseRoleMapMenus.Select(t => t.MenuId)?.ToList();
            baseRoleMapMenus.ForEach(x =>
            {
                var childIds = menuInfos.Where(t => t.ParentId == x.MenuId)?.Select(t => t.Id)?.ToList();
                if (childIds.Count > 0)
                {
                    childIds.ForEach(p =>
                    {
                        if (!checkMenuIds.Contains(p) && !removeIds.Contains(x.MenuId))
                            removeIds.Add(x.MenuId);
                    });
                }
            });
            checkMenuIds = checkMenuIds.Where(t => !removeIds.Contains(t))?.ToList();
            List<RoleMapMenuInfo> roleMapMenuInfos = new List<RoleMapMenuInfo>();
            List<MainMenuEntity> sortMenus = menuInfos.OrderBy(t => t.Sort)?.ToList();
            OperMenus(sortMenus, ref roleMapMenuInfos, 0);
            BaseGenericResult<RoleMapMenuResult> treelist = new BaseGenericResult<RoleMapMenuResult>();
            treelist.Data = new RoleMapMenuResult();
            treelist.Data.Checks = checkMenuIds;
            treelist.Data.list = roleMapMenuInfos;
            return treelist;
        }
        /// <summary>
        /// 获取所有菜单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<RoleMapMenuResult> GetMealsTree()
        {
            List<MainMenuEntity> menuInfos = rep_mainMenu.Query(new BaseQuery(), t => t.Where(m => m.Type == 0))?.ToList();
            List<RoleMapMenuInfo> roleMapMenuInfos = new List<RoleMapMenuInfo>();
            List<MainMenuEntity> sortMenus = menuInfos.OrderBy(t => t.Sort)?.ToList();
            OperMenus(sortMenus, ref roleMapMenuInfos, 0);
            BaseGenericResult<RoleMapMenuResult> treelist = new BaseGenericResult<RoleMapMenuResult>();
            treelist.Data = new RoleMapMenuResult();
            treelist.Data.list = roleMapMenuInfos;
            return treelist;
        }
        /// <summary>
        /// 生成菜单树
        /// </summary>
        /// <param name="mainMenus"></param>
        /// <param name="roleMapMenuInfos"></param>
        /// <param name="level"></param>
        private void OperMenus(List<MainMenuEntity> mainMenus, ref List<RoleMapMenuInfo> roleMapMenuInfos, int level)
        {
            var list = mainMenus.Where(t => t.Level == level)?.ToList();
            if (list.Count < 1)
                return;
            foreach (var item in list)
            {
                RoleMapMenuInfo roleMapMenuInfo = new RoleMapMenuInfo();
                roleMapMenuInfo.id = item.Id;
                roleMapMenuInfo.label = item.Title;
                roleMapMenuInfo.parentId = item.ParentId;
                var model = roleMapMenuInfos.FirstOrDefault(t => t.id == item.ParentId);
                if (model == null)
                {
                    roleMapMenuInfo.children = new List<RoleMapMenuInfo>();
                    roleMapMenuInfos.Add(roleMapMenuInfo);
                }
                else
                {
                    model.children.Add(new RoleMapMenuInfo()
                    {
                        id = item.Id,
                        parentId = model.parentId,
                        label = item.Title,
                        children = new List<RoleMapMenuInfo>()
                    });
                }
            }
            level += 1;
            OperMenus(mainMenus, ref roleMapMenuInfos, level);
        }
        /// <summary>
        /// 根据角色名后缀加载响应角色集合
        /// </summary>
        /// <param name="endName"></param>
        /// <returns></returns>
        public BaseGenericResult<List<RoleResult>> QueryRoles(string endName)
        {
            BaseGenericResult<List<RoleResult>> baseResult = new BaseGenericResult<List<RoleResult>>();
            baseResult.Data = rep_mainRole.Query(new BaseQuery(),
                  t => t.Where(m => m.Name.EndsWith(endName)))?.Select(x => new RoleResult()
                  {
                      Name = x.Name,
                      Id = x.Id
                  })?.ToList();
            return baseResult;
        }
    }
}
